package com.example.springbootdemo.service;

import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Service;

import java.beans.Transient;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;

@Service
public class AsyncService {

    /**
     * 简单的异步方法 - 无返回值
     * 自定义线程池配置。因为配置了多个线程池，所以Spring中能找到唯一的实现TaskExecutor接口不成立。并且没有Bean名字叫taskExecutor的Bean。所以这里是使用SimpleAsyncTaskExecutor。
     * 如果配置了一个ThreadPoolTaskExecutor线程池，那么@Async能找到我们写的myTaskExecutor线程池。或者，如果我们的myTaskExecutor的bean名称改为taskExecutor，那么@Async也能获取到。
     */
    @Async
    public void asyncMethodWithoutReturn() {
        String threadName = Thread.currentThread().getName();
        System.out.println("🟢 异步方法开始执行，线程: " + threadName);
        try {
            System.out.println("⏳ 线程 " + threadName + " 开始睡眠3秒");
            TimeUnit.SECONDS.sleep(3); // 模拟耗时操作
            System.out.println("✅ 线程 " + threadName + " 睡眠结束");
        } catch (InterruptedException e) {
            System.out.println("❌ 线程 " + threadName + " 被中断");
            Thread.currentThread().interrupt();
        }
        System.out.println("🔴 异步方法执行完成，线程: " + threadName);
    }

    /**
     * 带返回值的异步方法
     * 这里指定了使用myTaskExecutor，所以可以使用myTaskExecutor执行。
     */
    @Async("myTaskExecutor")
    public Future<String> asyncMethodWithReturn() {
        String threadName = Thread.currentThread().getName();
        System.out.println("🟢 带返回值异步方法开始，线程: " + threadName);
        try {
            System.out.println("⏳ " + threadName + " 开始睡眠2秒");
            TimeUnit.SECONDS.sleep(2);
            String result = "异步处理完成，结果: " + System.currentTimeMillis();
            System.out.println("✅ 线程 " + threadName + " 生成结果: " + result);
            return new AsyncResult<>(result);
        } catch (InterruptedException e) {
            System.out.println("❌ 线程 " + threadName + " 被中断");
            Thread.currentThread().interrupt();
            return new AsyncResult<>("任务被中断");
        }
    }

    /**
     * 模拟发送邮件的异步方法
     * 这里指定了使用ioTaskExecutor，所以可以使用ioTaskExecutor执行。
     */
    @Async("ioTaskExecutor")
    public void sendEmail(String to, String content) {
        String threadName = Thread.currentThread().getName();
        System.out.println("🟢 开始发送邮件，线程: " + threadName);
        System.out.println("📧 收件人: " + to + ", 内容: " + content);
        try {
            System.out.println("⏳ 线程 " + threadName + " 正在发送邮件...");
            TimeUnit.SECONDS.sleep(1);
            System.out.println("✅ 邮件发送成功: " + content);
        } catch (InterruptedException e) {
            System.out.println("❌ 邮件发送被中断");
            Thread.currentThread().interrupt();
        }
        System.out.println("🔴 邮件发送任务完成，线程: " + threadName);
    }
}